package com.cwt_taxi_xa.protocol.voice;

import android.app.ProgressDialog;
import android.text.TextUtils;
import android.util.Log;

import com.cwt_taxi_xa.ActivityACC;
import com.cwt_taxi_xa.MainApplication;
import com.cwt_taxi_xa.constants.Constants;
import com.cwt_taxi_xa.protocol.MCUUtil;
import com.cwt_taxi_xa.protocol.card.cmd.BaseCmd;
import com.cwt_taxi_xa.service.SerialPortService;
import com.cwt_taxi_xa.util.AppLog;
import com.cwt_taxi_xa.util.ByteArrayUtil;
import com.cwt_taxi_xa.util.CompareUtil;
import com.cwt_taxi_xa.util.FileOper;
import com.cwt_taxi_xa.util.IntUtil;
import com.cwt_taxi_xa.util.Tools;
import com.example.updatejniso.JniInterface;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferListener;

/**
 * Created by undi on 2019/9/5 09:23
 * 声耕升级
 */
public class FocalAcousticsUpgrade {

    private String TAG = "AcousticsUpgrade";
    //正则表达式匹配版本号
    private String regex = "SoftV\\d{3,5}HardV\\d{3,5}";
    private String regexSG = "SG-SoftV\\d{3,5}HardV\\d{3,5}";
    //正则表达式获取版本号
    private String regexCompile = "SoftV(\\d{3,5})HardV(\\d{3,5})";//注意此处关键字有括号
    private String regexCompileSG = "SG-SoftV(\\d{3,5})HardV(\\d{3,5})";//注意此处关键字有括号
    //升级文件路径
    private String fileDownPatch = "";
    //初始文件目录
    private boolean isSetPath = false;

    private int hardwareVER = -1;

    private int softwareVER = -1;

    private String fileCrc = "";

    private boolean hasDevice = false;

    private boolean isDownloadFile = false;

    public ResponseState responseState = new ResponseState();

    private ResendTask resendTask = new ResendTask();

    ViewManager viewManager;

    public FocalAcousticsUpgrade() {
        viewManager = new ViewManager(MainApplication.getInstance());
    }

    public void setHasDevice(boolean hasDevice) {
        this.hasDevice = hasDevice;
    }

    public int getResultState(){
        return responseState.getResultState();
    }

    public int getHardwareVER() {
        return hardwareVER;
    }

    public int getSoftwareVER() {
        return softwareVER;
    }

    public boolean versionCheck(String version){
        boolean result = false;
        //还未查到版本号
        if(!ActivityACC.accon){
            Log.e(TAG,"8BF4 versionCheck: device is acc off");
            responseState.setResultState(ResponseState.RESULT_STATE_ACC_OFF);
        }else if(hardwareVER < 0 || softwareVER < 0 || !hasDevice){
            Log.e(TAG,"8BF4 versionCheck: device is null");
            responseState.setResultState(ResponseState.RESULT_STATE_DEVICE);
        }else if((responseState.getSeq() > 0) ||(isSetPath && getResultState() == ResponseState.RESULT_STATE_PROGRESS)){
            //正在升级
            Log.d(TAG,"8BF4 versionCheck: is null");
            responseState.setResultState(ResponseState.RESULT_STATE_PROGRESS);
        }else if((responseState.getSeq() > 0) ||(isSetPath && getResultState() == ResponseState.RESULT_STATE_PROGRESS)){
            //正在升级
            Log.d(TAG,"8BF4 versionCheck: is null");
            responseState.setResultState(ResponseState.RESULT_STATE_PROGRESS);
        }else if(!TextUtils.isEmpty(version)){
            //正则匹配,以免获取版本号报错
            if(version.matches(regex)){
                Log.d(TAG,"version:" + version +"  matches:true");
                Pattern pattern = Pattern.compile(regexCompile);
                Matcher matcher = pattern.matcher(version);
                if(matcher.find()) {
                    int softV = parseInt(matcher.group(1));//需要在version.matches(regex)之后
                    int hardV = parseInt(matcher.group(2));
                    Log.d(TAG,"softV:" + softV + " hardV:" + hardV + " softwareVER:" + softwareVER + " hardwareVER:" + hardwareVER);
                    if(softV > -1 && hardV > -1){
                       if(!CompareUtil.equals(softV,softwareVER) && CompareUtil.equals(hardV,hardwareVER)){
                           result = true;

                       }else{
                           Log.d(TAG,"8BF4 versionCheck softV:-1 or hardVs>-1");
                           responseState.setResultState(ResponseState.RESULT_STATE_LATEST_VERSION);
                       }
                    }else{
                        //版本号解析错误,应该不会出现
                        Log.d(TAG,"8BF4 versionCheck softV:-1 or hardVs>-1");
                        responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
                    }
                }else{
                    //没有找到匹配的版本号,应该不会出现
                    Log.d(TAG,"8BF4 versionCheck version:" + version + "  matcher.find():false");
                    responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
                }
            }if(version.matches(regexSG)){
                Log.d(TAG,"version:" + version +"  matches:true");
                Pattern pattern = Pattern.compile(regexCompileSG);
                Matcher matcher = pattern.matcher(version);
                if(matcher.find()) {
                    int softV = parseInt(matcher.group(1));//需要在version.matches(regex)之后
                    int hardV = parseInt(matcher.group(2));
                    Log.d(TAG,"softV:" + softV + " hardV:" + hardV + " softwareVER:" + softwareVER + " hardwareVER:" + hardwareVER);
                    if(softV > -1 && hardV > -1){
                        if(!CompareUtil.equals(softV,softwareVER) && CompareUtil.equals(hardV,hardwareVER)){
                            result = true;

                        }else{
                            Log.d(TAG,"8BF4 versionCheck softV:-1 or hardVs>-1");
                            responseState.setResultState(ResponseState.RESULT_STATE_LATEST_VERSION);
                        }
                    }else{
                        //版本号解析错误,应该不会出现
                        Log.d(TAG,"8BF4 versionCheck softV:-1 or hardVs>-1");
                        responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
                    }
                }else{
                    //没有找到匹配的版本号,应该不会出现
                    Log.d(TAG,"8BF4 versionCheck version:" + version + "  matcher.find():false");
                    responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
                }
            }else{
                //不匹配
                responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
                Log.d(TAG,"8BF4 versionCheck version:" + version + "  matches:false");
            }
        }else{
            //版本名称不合法
            Log.d(TAG,"8BF4 versionCheck version: is null");
            responseState.setResultState(ResponseState.RESULT_STATE_FILE_ILLEGAL);
        }
        return result;
    }
    /**
     * 解析升级文件前需设置好文件目录
     */
    private void setFilePath(){
        MCUUtil.mVoiceTool.closeTimer();
        if(!TextUtils.isEmpty(fileDownPatch)){
            JniInterface.fwPathToJNI(fileDownPatch,true);
            isSetPath = true;
        }
    }

    public void setFilePath(String fileDownPatch){
        this.fileDownPatch = fileDownPatch;
        if(!TextUtils.isEmpty(fileDownPatch)){
            JniInterface.fwPathToJNI(fileDownPatch,true);
            isSetPath = true;
        }
    }

    /**
     * 解析升级协议
     * @param data
     */
    public void ackAndUpdate(byte[] data){
        Log.e(TAG,"JniInterface.cmdFromJNI start");
        resendTask.cancelResend();
        if(isSetPath){
            //转发
            JniInterface.cmdFromJNI(data,data.length);
            Log.e(TAG,"JniInterface.cmdFromJNI");
            //获取处理后的命令
            if (data[5] == (byte) 0x0E) {
                Log.i(TAG,"JniInterface update success!");
                isSetPath = false;
                try {
                    MainApplication.handler.post(new Runnable() {
                        @Override
                        public void run() {
                            viewManager.success();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
                responseState.setResultState(ResponseState.RESULT_STATE_SUCCESS);
                if(!TextUtils.isEmpty(fileDownPatch)){
                    File file = new File(fileDownPatch);
                    if(file.exists()){
                        file.delete();
                    }
                }
            }else{
                responseState.setResultState(ResponseState.RESULT_STATE_PROGRESS);
                Integer result = new Integer(0);
                byte[] buffer = JniInterface.cmdToJNI(result);
                Log.d(TAG, "JniInterface.cmdToJNI");
                sendSerialDataCache(buffer);
                if (result == 1) {
                    buffer = JniInterface.cmdToJNI(result);
                    Log.d(TAG, "JniInterface.cmdToJNI result == 1");
                    //转发
                    sendSerialDataCache(buffer);
                }

                try {
                    if(data[4] == (byte) 0xA1 && data[5] == (byte) 0x03){
                        Log.e(TAG, "ackAndUpdate data[5] == (byte) 0xA1");
                        MainApplication.handler.post(new Runnable() {
                            @Override
                            public void run() {
                                Log.e(TAG, "ackAndUpdate showProgressDialog");
                                viewManager.showFloatBall();

                            }
                        });

                    }else{
                        Log.e(TAG, "ackAndUpdate data[5] == " + data[5]);
                        MainApplication.handler.post(new Runnable() {
                            @Override
                            public void run() {
                                Log.e(TAG, "ackAndUpdate getProcess() == " + JniInterface.getProcessFromJNI());
                                viewManager.setProgress(JniInterface.getProcessFromJNI());
                            }
                        });
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }else{
            Log.e(TAG,"JniInterface fwPathToJNI not set!");
        }
    }

    private void sendSerialDataCache(byte[] buffer){
        if(buffer != null && buffer.length > 0){
            try {
                Log.d(TAG,"发送声耕指令 " + (Tools.parseByte2HexStr(BaseCmd.byteToSubstring(buffer,buffer.length - 4,VoiceTool.subLength))) + " length:" + ( buffer == null?"null":buffer.length));
            } catch (Exception e) {
                e.printStackTrace();
            }
            //debug(buffer);
            if(buffer.length > 3000){
                resendTask.saveCache(buffer);
                resendTask.startResend();
            }

            byte[] bufferCache = MCUUtil.getSerialMCUData(MCUUtil.touchuan(buffer));
            //Log.d(TAG,"发送声耕指令 bufferCache:" + Tools.parseByte2HexStr(bufferCache)) ;
            if(bufferCache != null){
                SerialPortService.getInstance().sendSerialData7(bufferCache);
            }
        }
    }

    /**
     * 解析设备版本号
     * @param buffer
     */
    public void deviceInfo(byte[] buffer){
        setHasDevice(true);
        responseState.setResultState(ResponseState.RESULT_STATE_UNKNOWN);
        try {
            int index = 5;
            if(buffer != null){
                //uint32 DeviceNUM 设备序列号：每个设备的序列号是唯一的
                int deviceNUM = IntUtil.littleBytesToInt32(BaseCmd.byteToSubstring(buffer,index,4));
                index += 4;
                //uint16 HardwareVER*100 硬件版本号
                hardwareVER = IntUtil.littleBytesToInt16(BaseCmd.byteToSubstring(buffer,index,2));
                index += 2;
                //uint16 SoftwareVER*100 SoftwareVER 软件版本号
                softwareVER = IntUtil.littleBytesToInt16(BaseCmd.byteToSubstring(buffer,index,2));
                index += 2;
                //uint16 ProtocolVER*100 ProtocolVER 协议版本号
                int protocolVER = IntUtil.littleBytesToInt16(BaseCmd.byteToSubstring(buffer,index,2));
                index += 2;
                //uint16 BootVER*100 BootloaderVER Boot版本号
                int bootloaderVER = IntUtil.littleBytesToInt16(BaseCmd.byteToSubstring(buffer,index,2));
                index += 1;
                //uint8  DeviceStatusDeviceStatus 设备状态：0x00 正常、0x01 异常
                int deviceStatus = buffer[index];
                //例如：硬件版本号为1.03表示为HardwareVER=1.03*100
                AppLog.d(TAG,"deviceNUM:" + deviceNUM + " hardwareVER:" + hardwareVER + " softwareVER:" + softwareVER);
                AppLog.d(TAG,"protocolVER:" + protocolVER + " bootloaderVER:" + bootloaderVER + " deviceStatus:" + deviceStatus);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startCrc(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                if(!TextUtils.isEmpty(fileDownPatch)){
                    File file = new File(fileDownPatch);
                    if(file.exists()){
                        byte[] crc = ByteArrayUtil.get2Crc16(FileOper.getBytesFromFile(file));
                        String downloadFileCrc = Tools.parseByte2HexStr(crc);
                        if(!TextUtils.isEmpty(fileCrc) && !TextUtils.isEmpty(downloadFileCrc)){
                            setFilePath();
                            //发送升级帧
                            if(isSetPath){
                                MCUUtil.mVoiceTool.updateFrame();
                            }
                        }else{
                            //crc校验失败
                            responseState.setResultState(ResponseState.RESULT_STATE_CRC_FAILED);
                        }
                    }else{
                        Log.e(TAG, "startCrc：----->!file.exists()");
                        responseState.setResultState(ResponseState.RESULT_STATE_FILE_ERROR);
                    }
                }else{
                    Log.e(TAG, "startCrc：----->TextUtils.isEmpty(fileDownPatch)");
                    responseState.setResultState(ResponseState.RESULT_STATE_FILE_ERROR);
                }
            }
        }).start();


    }

    FTPDataTransferListener mFTPDataTransferListener = new FTPDataTransferListener() {
        @Override
        public void transferred(int arg0) {
            //正在下载
            Log.i(TAG, "FTPDataTransferListener：----->transferred: " + arg0);
        }

        @Override
        public void started() {
            isDownloadFile = true;
            //开始下载
            Log.i(TAG, "FTPDataTransferListener：----->started");
        }

        @Override
        public void failed() {
            isDownloadFile = false;
            //下载失败
            Log.e(TAG, "FTPDataTransferListener：----->failed");
            responseState.setResultState(ResponseState.RESULT_STATE_SERVER_ERROR);
        }

        @Override
        public void completed() {
            isDownloadFile = false;
            //下载成功
            Log.i(TAG, "FTPDataTransferListener：----->completed");
            startCrc();
        }

        @Override
        public void aborted() {
            isDownloadFile = false;
            //被取消
            Log.i("TAG", "FTPDataTransferListener：----->aborted");
            responseState.setResultState(ResponseState.RESULT_STATE_SERVER_ERROR);
        }
    };

    public void doCheckFTP(final String ftpPath, final int ftpPort, final String userName, final String password, final String fileName,int fileSize,String crcCheckSum) {
        this.fileCrc = crcCheckSum;
        new Thread(new Runnable() {
            @Override
            public void run() {
                FTPClient client = new FTPClient();
                //连接服务器
                try {
                    client.connect(ftpPath, ftpPort);//其中Host为Ftp地址，端口为固定的21
                } catch (Exception e) {
                    e.printStackTrace();
                    responseState.setResultState(ResponseState.RESULT_STATE_CONNECT_ERROR);
                    return;
                }
                //登录服务器
                try {
                    client.login(userName, password);
                } catch (Exception e) {
                    e.printStackTrace();
                    responseState.setResultState(ResponseState.RESULT_STATE_LOG_IN_ERROR);
                    return;
                }
                //文件浏览
                String downloadFilePath = null;
                try {
                    final String[] file = client.listNames();
                    for (int i = 0; i < file.length; i++) {
                        Log.i("TAG", "文件名：----->" + file[i]);
                        if (client == null) {
                            break;
                        }
                        if (file[i] == null) {
                            break;
                        }
                        if (file[i].equals(fileName)) {
                            Log.i("TAG", "download 文件名：----->" + file[i]);
                            downloadFilePath = file[i];
                            //第一个参数为ftp上的文件名，第二个参数为下载到本地后需要保存文件的名字，第三个为下载过程中的监听器
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    responseState.setResultState(ResponseState.RESULT_STATE_FILE_ERROR);
                    return;
                }
                //下载服务器
                if (!TextUtils.isEmpty(downloadFilePath)) {
                    final File file_down = new File(Constants.SDPath + fileName);
                    if (file_down.exists()) {
                        file_down.delete();
                    }
                    try {
                        fileDownPatch = file_down.getPath();
                        client.download(downloadFilePath, file_down, mFTPDataTransferListener);
                    } catch (Exception e) {
                        e.printStackTrace();
                        //responseState.setResultState(ResponseState.RESULT_STATE_SERVER_ERROR);
                    }
                }else{
                    responseState.setResultState(ResponseState.RESULT_STATE_FILE_ERROR);
                }
            }
        }).start();
    }

    private int parseInt(String value){
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return -1;
    }

    private static int enableSize = 1024 ;//512 + ;
    private static int mSleepTime = 10;
    private static boolean needSleep = false;
    private void debug(final byte[] buffer){
        new Thread(new Runnable() {
            @Override
            public void run() {
                //分包重发机制
                int arrayLength = buffer.length;
                if(buffer != null && arrayLength > enableSize){
                    int size = arrayLength/enableSize;
                    int endSize = arrayLength % enableSize;
                    AppLog.d(TAG,"sendSerialData7Test size:" + size + " endSize:" + endSize);

                    for(int i = 0; i < size; i ++){
                        byte[] itemBuffer = new byte[enableSize];
                        System.arraycopy(buffer,i * enableSize,itemBuffer,0,enableSize);
                        if(needSleep){
                            try {
                                Thread.sleep(mSleepTime);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        Log.d(TAG,"cmdToJNI length:" + ( itemBuffer == null?"null":itemBuffer.length)+ " :"+Tools.parseByte2HexStr(itemBuffer));
                    }

                    if(endSize != 0){
                        byte[] itemBuffer = new byte[endSize];
                        System.arraycopy(buffer,size * enableSize,itemBuffer,0,endSize);
                        Log.d(TAG,"cmdToJNI length:" + ( itemBuffer == null?"null":itemBuffer.length)+ " :"+Tools.parseByte2HexStr(itemBuffer));
                        if(needSleep){
                            try {
                                Thread.sleep(mSleepTime);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //sendSerialData7(itemBuffer);
                    }
                }
            }
        }).start();
    }

    ProgressDialog pBar;
    private synchronized void showProgressDialog() {
        if(pBar == null){
            pBar = new ProgressDialog(MainApplication.getInstance());
            pBar.setCanceledOnTouchOutside(false);
            pBar.setTitle("正在下载");
            pBar.setMax(100);
            pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//		pBar.setButton( DialogInterface.BUTTON_POSITIVE,"下载不动？ 刷新一下~"
//				,new DialogInterface.OnClickListener(){
//			  public void onClick(DialogInterface d, int i) {
//				  pBar.dismiss();
//				  doCheckFTP();
//			  }
//			});
            pBar.show();
        }
    }
    private synchronized void hideProgressDialog() {
        if(pBar != null){
            pBar.dismiss();
        }
    }
    private synchronized void setDialogProgress(int value){
        if(pBar != null){
            pBar.setProgress(value);
        }
    }
}
